package api

import (
	"go-weiqi-system/config"
	"go-weiqi-system/internal/models"
	"go-weiqi-system/internal/utils"

	"github.com/gin-gonic/gin"
)

type AppointmentController struct{}

// TimeSlots 获取约棋时间段列表
func (ctrl *AppointmentController) TimeSlots(c *gin.Context) {
	var timeSlots []models.AppointmentTime
	config.DB.Where("status = ?", 1).
		Order("sort desc, id desc").
		Find(&timeSlots)

	utils.Success(c, timeSlots)
}

// Recommend 推荐约棋时间段
func (ctrl *AppointmentController) Recommend(c *gin.Context) {
	var timeSlots []models.AppointmentTime
	config.DB.Where("status = ? AND is_recommended = ?", 1, 1).
		Order("sort desc, id desc").
		Limit(3).
		Find(&timeSlots)

	utils.Success(c, timeSlots)
}

// Index 约棋报名列表（公开）
func (ctrl *AppointmentController) Index(c *gin.Context) {
	var param models.PageParam
	if err := c.ShouldBindQuery(&param); err != nil {
		param.Page = 1
		param.PageSize = 10
	}

	timeSlotID := c.Query("time_slot_id")
	status := c.Query("status")

	var appointments []models.Appointment
	var total int64

	db := config.DB.Model(&models.Appointment{}).Preload("User").Preload("AppointmentTime")

	if timeSlotID != "" {
		db = db.Where("time_slot_id = ?", timeSlotID)
	}
	if status != "" {
		db = db.Where("status = ?", status)
	}

	db.Count(&total)
	db.Order("id desc").
		Offset(param.GetOffset()).
		Limit(param.GetPageSize()).
		Find(&appointments)

	utils.Success(c, models.PageResponse{
		List:     appointments,
		Total:    total,
		Page:     param.GetPage(),
		PageSize: param.GetPageSize(),
	})
}

// MyList 我的约棋列表
func (ctrl *AppointmentController) MyList(c *gin.Context) {
	userID, _ := c.Get("user_id")

	var param models.PageParam
	if err := c.ShouldBindQuery(&param); err != nil {
		param.Page = 1
		param.PageSize = 10
	}

	var appointments []models.Appointment
	var total int64

	db := config.DB.Model(&models.Appointment{}).
		Where("user_id = ?", userID).
		Preload("AppointmentTime")

	db.Count(&total)
	db.Order("id desc").
		Offset(param.GetOffset()).
		Limit(param.GetPageSize()).
		Find(&appointments)

	utils.Success(c, models.PageResponse{
		List:     appointments,
		Total:    total,
		Page:     param.GetPage(),
		PageSize: param.GetPageSize(),
	})
}

// Create 创建约棋
func (ctrl *AppointmentController) Create(c *gin.Context) {
	userID, _ := c.Get("user_id")

	var req struct {
		TimeSlotID      uint   `json:"time_slot_id" binding:"required"`
		AppointmentDate string `json:"appointment_date" binding:"required"`
		Opponent        string `json:"opponent"`
		Notes           string `json:"notes"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		utils.Error(c, "参数错误")
		return
	}

	// 检查时间段是否存在
	var timeSlot models.AppointmentTime
	if err := config.DB.First(&timeSlot, req.TimeSlotID).Error; err != nil {
		utils.Error(c, "时间段不存在")
		return
	}

	// 检查时间段状态
	if timeSlot.Status != 1 {
		utils.Error(c, "该时间段已关闭")
		return
	}

	// 检查是否已报名
	var count int64
	config.DB.Model(&models.Appointment{}).
		Where("user_id = ? AND time_slot_id = ? AND appointment_date = ? AND status != ?",
			userID, req.TimeSlotID, req.AppointmentDate, "已取消").
		Count(&count)

	if count > 0 {
		utils.Error(c, "您已报名该时间段")
		return
	}

	// 检查人数限制
	if timeSlot.MaxParticipants > 0 && timeSlot.CurrentCount >= timeSlot.MaxParticipants {
		utils.Error(c, "该时间段人数已满")
		return
	}

	// 创建约棋
	appointment := models.Appointment{
		UserID:          userID.(uint),
		TimeSlotID:      req.TimeSlotID,
		AppointmentDate: req.AppointmentDate,
		Opponent:        req.Opponent,
		Notes:           req.Notes,
		Status:          "待确认",
	}

	if err := config.DB.Create(&appointment).Error; err != nil {
		utils.Error(c, "创建失败")
		return
	}

	// 更新时间段人数
	config.DB.Model(&models.AppointmentTime{}).
		Where("id = ?", req.TimeSlotID).
		UpdateColumn("current_count", config.DB.Raw("current_count + ?", 1))

	utils.Success(c, appointment, "报名成功")
}

// Cancel 取消约棋
func (ctrl *AppointmentController) Cancel(c *gin.Context) {
	userID, _ := c.Get("user_id")

	var req struct {
		ID uint `json:"id" binding:"required"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		utils.Error(c, "参数错误")
		return
	}

	var appointment models.Appointment
	if err := config.DB.Where("id = ? AND user_id = ?", req.ID, userID).First(&appointment).Error; err != nil {
		utils.Error(c, "约棋记录不存在")
		return
	}

	if appointment.Status == "已取消" {
		utils.Error(c, "该约棋已取消")
		return
	}

	if appointment.Status == "已完成" {
		utils.Error(c, "已完成的约棋无法取消")
		return
	}

	// 更新状态
	if err := config.DB.Model(&appointment).Update("status", "已取消").Error; err != nil {
		utils.Error(c, "取消失败")
		return
	}

	// 更新时间段人数
	config.DB.Model(&models.AppointmentTime{}).
		Where("id = ?", appointment.TimeSlotID).
		Update("current_count", config.DB.Raw("current_count - ?", 1))

	utils.Success(c, nil, "取消成功")
}
